﻿using System;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.Security;
using ChampionsLeagueBets.Domain;
using SharpArch.Domain;
using SharpArch.NHibernate.Contracts.Repositories;

namespace ChampionsLeagueBets.Web.Mvc.Authentication
{
	public static class WebAuthentication
	{
		private const string UserKey = "User";
		private const int SessionTime = 20;

		private static string GetUserKey(int userId)
		{
			return string.Format("{0}_{1}", UserKey, userId);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="user"></param>
		/// <returns></returns>
		public static void CreatePrincipal(User user)
		{
			if (user == null)
				throw new ArgumentNullException("user");

			HttpContext.Current.Cache.Remove(GetUserKey(user.Id));

			HttpContext.Current.Cache.Add(GetUserKey(user.Id), user, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High, null);

			FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.FullName, DateTime.Now, DateTime.Now.AddMinutes(SessionTime), true, user.Id.ToString());

			HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public static bool ApplyRightPrincipal()
		{
			if (!HttpContext.Current.User.Identity.IsAuthenticated)
				return false;

			HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

			if (authCookie == null)
				return false;

			FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

			if (authTicket == null)
				return false;

			if (string.IsNullOrEmpty(authTicket.UserData))
				return false;

			int userId;
			if (!Int32.TryParse(authTicket.UserData, out userId))
				return false;

			if (HttpContext.Current.Cache[GetUserKey(userId)] == null)
			{
				INHibernateRepository<User> userRepository = SafeServiceLocator<INHibernateRepository<User>>.GetService();
				HttpContext.Current.Cache.Add(GetUserKey(userId), userRepository.Get(userId), null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.High, null);
			}

			User user = (User)HttpContext.Current.Cache[GetUserKey(userId)];

			HttpContext.Current.User = RightPrincipal.Create(HttpContext.Current.User.Identity, user);

			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		public static void RemovePrincipal()
		{
			if (RightPrincipal.CurrentUser == null)
				return;

			HttpContext.Current.Cache.Remove(GetUserKey(RightPrincipal.CurrentUser.Id));
			FormsAuthentication.SignOut();
		}
	}
}

